package com.zhb.down

import android.os.Handler
import android.os.Looper
import okhttp3.*
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream

class DownHelper private constructor() {

    private val okHttpClient: OkHttpClient = OkHttpClient()

    /**
     * @param url      下载连接
     * @param localUrl 储存下载文件的路径,带名称
     * @param listener 下载监听
     */
    fun download(url: String?, localUrl: String, listener: OnDownloadListener) {
        val request =
            url?.let { Request.Builder().addHeader("Accept-Encoding", "identity").url(it).build() }
        if (request != null) {
            okHttpClient.newCall(request).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    // 下载失败
                    ZLog.e("下载失败", e)
                    Handler(Looper.getMainLooper()).post { listener.onDownloadFailed() }
                }

                @Throws(IOException::class)
                override fun onResponse(call: Call, response: Response) {
                    var `is`: InputStream? = null
                    val buf = ByteArray(2048)
                    var len: Int
                    var fos: FileOutputStream? = null
                    if (!isExistDir(localUrl)) {
                        ZLog.e("下载目录不存在", NullPointerException("位置不存在"))
                        Handler(Looper.getMainLooper()).post { listener.onDownloadFailed() }
                        return
                    }
                    try {
                        `is` = response.body!!.byteStream()
                        val total = response.body!!.contentLength()
                        val file = File(localUrl)
                        fos = FileOutputStream(file)
                        var sum: Long = 0
                        while (`is`.read(buf).also { len = it } != -1) {
                            fos.write(buf, 0, len)
                            sum += len.toLong()
                            val progress = (sum * 1.0f / total * 100).toInt()
                            // 下载中
                            Handler(Looper.getMainLooper()).post { listener.onDownloading(progress) }
                        }
                        fos.flush()
                        // 下载完成
                        ZLog.d("下载成功")
                        Handler(Looper.getMainLooper()).post { listener.onDownloadSuccess() }
                    } catch (e: Exception) {
                        ZLog.e("下载写入文件异常", e)
                        Handler(Looper.getMainLooper()).post { listener.onDownloadFailed() }
                    } finally {
                        try {
                            `is`?.close()
                        } catch (e: IOException) {
                        }
                        try {
                            fos?.close()
                        } catch (e: IOException) {
                        }
                    }
                }
            })
        }
    }

    /**
     * @param saveDir
     * @return
     */
    private fun isExistDir(saveDir: String): Boolean {
        val downloadFile = File(saveDir)
        val fileDir = File(downloadFile.absoluteFile.parent)
        return fileDir.exists()
    }

    interface OnDownloadListener {
        /**
         * 下载成功
         */
        fun onDownloadSuccess()

        /**
         * @param progress 下载进度
         */
        fun onDownloading(progress: Int)

        /**
         * 下载失败
         */
        fun onDownloadFailed()
    }

    companion object {
        val instance: DownHelper by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { DownHelper() }
    }

}